# coding=utf-8
"""
author: jamon
"""
from enum import Enum
from typing import Literal


class NodeType(Enum):
    ROUTE = "route"
    SERVICE = "service"
    PROXY = "proxy"


NodeTypeName = Literal[NodeType.ROUTE, NodeType.SERVICE, NodeType.PROXY]
DbWay = Literal["local", "mongo_uri"]
Encode = Literal[0, 1]
LogLevel = Literal["debug", "info", "warn", "error", "DEBUG", "INFO",
                   "WARN", "ERROR"]


class TransportInfo(object):
    """端口配置信息"""

    def __init__(self, encode: Encode, host: str, port: int, token: str,
                 n_type: NodeTypeName):
        self.encode: Encode = encode
        self.host: str = host
        self.port: int = port
        self.token: str = token
        self.type: NodeTypeName = n_type


class RouteRule(object):
    """路由规则"""
    def __init__(self, route_info: dict):

        # 路由消息区间段规则
        self.range: dict[NodeTypeName, list[tuple[int, int]]] = {}
        if route_info:
            for _type, info in route_info.get("range", {}).items():
                self.range[_type] = info

            # 路由特殊的消息id规则
            self.special: dict[NodeTypeName, list[int]] = {}
            for _type, info in route_info.get("special", {}).items():
                self.special[_type] = info


class Config(object):
    """框架配置类"""
    def __init__(self, data: dict):
        # 业务接口代码路径 (从哪导入项目自定义的接口代码)
        self.api_path: str = data["api_path"]

        # 存储数据的方式
        self.available_way: DbWay = data["available_way"]

        # 节点所在主机地址
        self.host: str = data["host"]

        # http端口配置
        self.http: TransportInfo = TransportInfo(
            data["http"]["encode"], self.host, data["http"]["port"],
            data["http"]["token"], data["http"]["type"]
        )

        # 日志存放目录
        self.log_dir: str = data["log_dir"]
        # 日志等级
        self.log_level: LogLevel = data["log_level"]

        # mongo连接路径
        self.mongo_uri: str = data.get("mongo_rui", "")

        # 节点名
        self.name: str = data["name"]

        # 与哪些节点保持联系
        self.remote_ports: list[TransportInfo] = []
        for info in data.get("remote_ports", []):
            self.remote_ports.append(
                TransportInfo(
                    info["encode"], info["host"], info["port"],
                    info["token"], info["type"]
                )
            )

        # 监听的rpc端口
        self.rpc: TransportInfo = TransportInfo(
            data["rpc"]["encode"], self.host, data["rpc"]["port"],
            data["rpc"]["token"], data["rpc"]["type"]
        )

        # rpc的路由消息规则
        self.rpc_route_rule: RouteRule = RouteRule(
            data["rpc"].get("route", {}))

        # 节点类型
        self.type: str = data["type"]

        # websocket 监听端口
        self.websocket: TransportInfo = TransportInfo(
            data["websocket"]["encode"], self.host, data["websocket"]["port"],
            data["websocket"]["token"], data["websocket"]["type"]
        )

        self.frame_num: int = 60
        self.frame_broad_interval: int = 5
